#define  _CRT_SECURE_NO_WARNINGS 1
//#include "head.h"

//1、
//void GetMemory(char* p) // --> 传值调用(str变量的值-->str指向的NULL)，而不是str的地址
//{
//	p = (char*)malloc(100);
//}
//void test1()
//{
//	char* str = NULL;
//	GetMemory(str); //str依旧是NULL，只是把NULL传给形参p ,p有自己的空间
//	strcpy(str, "hello world"); //str为NULL，对空指针的解引用操作，程序崩溃
//	// 没有对malloc分配的空间进行释放，内存泄漏。
//	printf("%p\n", str);
//}
///*
//	C 语言中只有传值调用，所有函数参数都是通过 “值拷贝” 传递的。
//	这里 str 作为指针变量，传递的是它存储的地址（NULL）的副本，属于传值调用。
//	函数内部对形参 p 的修改（让它指向新内存）不会影响外部的 str，这也是代码存在逻辑错误的核心原因（str 始终为 NULL）。
//*/
//int main()
//{
//	test1();
//	return 0;
//}
//
///*
//	传值调用：
//	函数接收的是实参的副本（值的拷贝）。函数内部对形参的修改，不会影响外部实参本身。
//	
//	传址调用（严格来说，C 语言中没有真正的 “传址”，而是 “传递指针的值”）：
//	若实参是指针，函数接收的是指针的副本（地址的拷贝），此时通过指针解引用（*p）可以修改指针指向的内容，但修改指针本身（如让指针指向新地址）不会影响外部的指针变量。
//*/


//1、1 改进：
//void GetMemory(char** p)
//{
//	*p = (char*)malloc(100);
//}
//void test1()
//{
//	char* str = NULL;
//	GetMemory(&str); 
//	strcpy(str, "hello world");
//	printf(str); //ok
//
//    free(str);
//    str = NULL;
//}
//int main()
//{
//	test1();
//	return 0;
//}

//1、2 改进：
//char*  GetMemory(char* p)
//{
//	p = (char*)malloc(100);
//    return p;
//}
//void test1()
//{
//	char* str = NULL;
//	str = GetMemory(str);
//	strcpy(str, "hello world");
//	printf(str); //ok
//
//	free(str);
//	str = NULL;
//}
//int main()
//{
//	test1();
//	return 0;
//}

//1、3 改进：
//char* GetMemory()
//{
//	char* p = (char*)malloc(100);
//	return p;
//}
//void test1()
//{
//	char* str = NULL;
//	str = GetMemory();
//	strcpy(str, "hello world");
//	printf(str); //ok
//
//	free(str);
//	str = NULL;
//}
//int main()
//{
//	test1();
//	return 0;
//}

//1、4 --> 返回栈空间地址的问题
//char* GetMemory()
//{
//	char p[] = "hello world"; //--> p 放在栈区，函数退出，栈空间被销毁
//	//static char q[] = "hello world"; //--> q 放在静态区，函数退出，静态变量不会被销毁
//	return p;
//}
//void test1()
//{
//	char* str = NULL;
//	str = GetMemory(); //p 局部(临时)变量 释放 销毁
//	printf(str); //str就是野指针
//}
//int main()
//{
//	test1();
//	return 0;
//}

